package com.example.backend.security;

import com.example.backend.component.JwtTokenUtil;
import com.example.backend.enums.ResultCodeEnum;
import com.example.backend.security.custom.CustomAuthenticationToken;
import com.example.backend.service.mysql.permission.PermissionService;
import com.example.backend.utils.ResultJson;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

@Component
@RequiredArgsConstructor
@Slf4j
public class JwtAuthentication extends OncePerRequestFilter {

    private final JwtTokenUtil jwtTokenUtil;
    private final PermissionService permissionService;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String jwt = getJwt(request);
        if (jwt != null) {
            if (Boolean.TRUE.equals(jwtTokenUtil.isJwtValid(jwt))) {
                Map<String, Object> allClaims = jwtTokenUtil.getAllClaims(jwt);
                // 获取原始权限数据，通常是 List<Map<String, String>>
                Object permissionsObj = allClaims.get("permissions");
                List<SimpleGrantedAuthority> permissions = new ArrayList<>();
                if (permissionsObj instanceof List<?>) {
                    for (Object item : (List<?>) permissionsObj) {
                        if (item instanceof Map<?, ?> && ((Map<?, ?>) item).get("authority") instanceof String) {
                            String authority = (String) ((Map<?, ?>) item).get("authority");
                            permissions.add(new SimpleGrantedAuthority(authority));
                        }
                    }
                }
                CustomAuthenticationToken usernamePasswordAuthenticationToken = new CustomAuthenticationToken(allClaims.get("userId"), null, permissions);
                SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
            } else {
                ResultJson<Object> fail = ResultJson.fail(ResultCodeEnum.TOKEN_EXPIRED.getCode(), ResultCodeEnum.TOKEN_EXPIRED.getMessage());
                renderString(response, ResultJson.serialize(fail));
                return; // 停止后续逻辑执行
            }
        } else {
            Collection<SimpleGrantedAuthority> visitor = permissionService.getVisitor();
            UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(null, null, visitor);
            SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
        }
        doFilter(request, response, filterChain);
    }

    private String getJwt(HttpServletRequest request) {
        String jwt = request.getHeader("Authorization");
        if (jwt != null && jwt.startsWith("Bearer ")) {
            jwt = jwt.substring(7);
        }
        return jwt;
    }

    public void renderString(HttpServletResponse response, String content) {
        try {
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().write(content);
            response.getWriter().flush();
            response.getWriter().close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
